package cn.thoughtworks.school.controllers;

import cn.thoughtworks.school.annotations.Auth;
import cn.thoughtworks.school.entities.Organization;
import cn.thoughtworks.school.entities.User;
import cn.thoughtworks.school.entities.UserOrganization;
import cn.thoughtworks.school.entities.UserRole;
import cn.thoughtworks.school.entities.commands.CreateOrganizationCommand;
import cn.thoughtworks.school.entities.commands.CreateUserRoleCommand;
import cn.thoughtworks.school.exceptions.BusinessException;
import cn.thoughtworks.school.services.OrganizationService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.web.PageableDefault;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequestMapping("/api")
public class OrganizationController {

  @Autowired
  private OrganizationService organizationService;

  @GetMapping(value = "organizations/pageable")
  public ResponseEntity getOrganizationPageable(
    @PageableDefault(sort = {"id"},
      direction = Sort.Direction.DESC) Pageable pageable) {

    Page<Organization> organizations = organizationService.findByPageable(pageable);
    return ResponseEntity.ok(organizations);
  }

  @GetMapping(value = "organizations/users/{userId}")
  public ResponseEntity getOrganizationsByUserId(@PathVariable Long userId) {
    List<Organization> organizations = organizationService.findByUserId(userId);
    return ResponseEntity.ok(organizations);
  }

  @GetMapping(value = "organizations/{organizationId}")
  public ResponseEntity getOrganization(@PathVariable Long organizationId) throws BusinessException {
    Organization organization = organizationService.findById(organizationId);
    return ResponseEntity.ok(organization);
  }

  @GetMapping(value = "organizations/{organizationId}/users")
  public ResponseEntity getOrganizationUsers(@PathVariable Long organizationId) {
    List<UserRole> userRoles = organizationService.findOrganizationAdminsByOrganizationId(organizationId);
    return ResponseEntity.ok(userRoles);
  }

  @DeleteMapping(value = "organizations/{organizationId}/users/{userId}/roles")
  public ResponseEntity delOrganizationAdminRole(@PathVariable Long organizationId,
                                                 @PathVariable Long userId) {
    organizationService.deleteOrganizationAdminRole(organizationId,userId);
    return ResponseEntity.noContent().build();
  }

  @PutMapping(value = "organizations/users/roles")
  public ResponseEntity addOrganizationAdminRole(@RequestBody CreateUserRoleCommand createUserRoleCommand) {
    organizationService.addOrganizationAdminRole(createUserRoleCommand);
    return ResponseEntity.noContent().build();
  }

  @PutMapping(value = "organizations/{organizationId}")
  public ResponseEntity updateOrganization(@RequestBody Organization organization,
                                         @PathVariable Long organizationId) throws BusinessException {
    organization = organizationService.updateOrganization(organizationId, organization);
    return new ResponseEntity(organization, HttpStatus.NO_CONTENT);
  }

  @PostMapping(value = "organizations")
  public ResponseEntity createOrganization(@Auth User user,
                                           @RequestBody CreateOrganizationCommand createOrganizationCommand) {
    Organization organization = organizationService.createOrganization(createOrganizationCommand, user);
    return new ResponseEntity(organization, HttpStatus.CREATED);
  }

  @GetMapping(value = "userOrganizations/{organizationId}")
  public ResponseEntity getUserOrganizationsByOrganizationId(@PathVariable Long organizationId) {
    List<UserOrganization> userOrganizations = organizationService.findUserOrganizationsByOrganizationId(organizationId);
    return ResponseEntity.ok(userOrganizations);
  }


  @PostMapping(value = "organizations/{organizationId}/users")
  public ResponseEntity addUsersToOrganizations(@PathVariable("organizationId") Long organizationId,
                                                @RequestBody List<Long> userIds) {
    organizationService.addUsersToOrganizations(organizationId, userIds);

    return new ResponseEntity(HttpStatus.CREATED);
  }


  @PostMapping(value = "userOrganizations")
  public ResponseEntity addUserOrganization(@RequestBody UserOrganization userOrganization) {
    organizationService.addUserOrganization(userOrganization);

    return new ResponseEntity(HttpStatus.CREATED);
  }


}
